package com.example.origin.demo.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.example.origin.demo.utils.LocalCacheHolder;
import com.example.origin.demo.utils.VmUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;

@Slf4j
@RestController
public class DemoController implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

    @SneakyThrows
    @GetMapping("test")
    public String test() {
        Object abc = RequestContextHolder
                .currentRequestAttributes()
                .getAttribute("abc", RequestAttributes.SCOPE_REQUEST);
        System.out.println(abc);
        return "";

    }

    @SneakyThrows
    @GetMapping("testStore")
    public String testStore() {
        Path path = Paths.get("database");
        if (Files.notExists(path)) {
            Files.createDirectories(path);
        }
        Path file = Paths.get("database", "database.txt");
        if (Files.notExists(path)) {
            Files.createFile(file);
        }
        List<String> lines = new ArrayList<>();
        lines.add("how world");
        Files.write(file, lines, StandardOpenOption.APPEND);


        lines = Files.readAllLines(file);
        //for循环遍历读取每一行并输出
        for (String line : lines) {
            System.out.println(line);
        }
        return "test";
    }

    @GetMapping("testCache")
    public void testCache() {
        logAttributes();
        VmUtil.logBase();
        LocalCacheHolder.get("111", () -> new Byte[1024 * 1024]);
        VmUtil.logBase();
        LocalCacheHolder.get("222", () -> new Byte[1024 * 1024]);

        VmUtil.logBase();
        Byte[] bytes = testCache2();
        log.info("bytes:{}",bytes.length);
        logAttributes();

    }

    private static void logAttributes() {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        String[] attributeNames = requestAttributes.getAttributeNames(RequestAttributes.SCOPE_REQUEST);
        log.info("attributeNames:{}",String.join(",",attributeNames));
    }

    private Byte[] testCache2() {
        return LocalCacheHolder.get("222", () -> new Byte[1024]);
    }

    @GetMapping("testDiffMap")
    public void testDiffMap(){


    }


    private static <T> Map<String, Pair<Object, Object>> diffMap(T t, T t1) {
        Map<String, Object> map = BeanUtil.beanToMap(t);
        Map<String, Object> map1 = BeanUtil.beanToMap(t1);
        Map<String, Pair<Object,Object>> pairMap = MapUtil.newHashMap();
        for (Map.Entry<String, Object> stringObjectEntry : map.entrySet()) {
            String key = stringObjectEntry.getKey();
            Object value = stringObjectEntry.getValue();
            Object value1 = map1.get(key);

            if (ObjectUtil.isAllEmpty(value,value1)) {
                continue;
            }
            if ((ObjectUtil.isBasicType(value1)
                    || value1 instanceof CharSequence
                    || value1 instanceof Date)
                    && (ObjectUtil.isBasicType(value)
                    || value instanceof CharSequence
                    || value instanceof Date)) {
                if (ObjectUtil.notEqual(value1,value)) {
                    pairMap.put(key, Pair.of(value,value1));
                }
            }
        }
        return pairMap;
    }

    @SneakyThrows
    @GetMapping("testPartitionRead")
    public String testPartitionRead() {
        int pageNo = 0;
        int pageSize =5;
        String str = "窗前明月光疑是地上霜举头望明月低头思故乡";
        partitionRead(pageNo, pageSize,(start,end)->{
            if (str.length()<=start) {
                return 0;
            }
            String substring = str.substring(start, end);
            System.out.println(substring);
            return substring.length();
        });
        return "";

    }


    private void partitionRead(Integer pageNo, Integer pageSize, BiFunction<Integer,Integer,Integer> function) {
        while (true){
            Integer start = PageUtil.getStart(pageNo, pageSize);
            Integer end = PageUtil.getEnd(pageNo, pageSize);
            Integer count = function.apply(start,end);
            if (count< pageSize) {
                break;
            }
            pageNo++;
        }
    }


}
